# -*- coding: utf8 -*-
"""
本文件功能是提供北斗网格码打码过程中，需要的工具函数
"""
from fraction import Fraction
from lat_lon_parser import parse
from typing import Tuple


def validate_longitude_or_latitude_format(long_or_lat:str) -> Tuple[bool,str]:
    """
    判断经度和纬度字符串描述是否合法
    :param long_or_lat: str ; 经度和纬度字符串表示
    :return: (bool,str) ; 是否合法标记，以及处理后标准字符串形式或错误原因
    """
    try:
        assert isinstance(long_or_lat, str)
    except:
        return False, f'param - {long_or_lat} - type is {ty},please change it into str'.format(ty=type(long_or_lat))
    else:
        long_or_lat_format = long_or_lat.upper().replace(' ', '').strip()
        try:
            parse(long_or_lat_format)
        except:
            return False, f'param - {long_or_lat_format} - is not standard format,please check'
        else:
            return True, long_or_lat_format


def transform_longitude_or_latitude_into_fraction(long_or_lat:str) -> Fraction:
    """
    转换经度和纬度字符串描述为精确分数格式
    :param long_or_lat: str ; 经度和纬度字符串表示
    :return: Fraction ; 精确的分数描述方式
    """
    # 将 W 和 S 修改为负值，将 N 和 E 修改为正值
    negative = -1 if long_or_lat.endswith(('W', 'S')) else 1
    # 提取经度和纬度中的度分秒
    long_or_lat_value = long_or_lat[1:]
    lang_or_lat_degree = lang_or_lat_minute = lang_or_lat_second = None
    # 度提取
    long_or_lat_value_list = long_or_lat_value.split('°')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_degree = long_or_lat_value_list[0]
        long_or_lat_value = long_or_lat_value_list[1]
    else:
        lang_or_lat_degree = 0
    # 分提取
    long_or_lat_value_list = long_or_lat_value.split('′')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_minute = long_or_lat_value_list[0]
        long_or_lat_value = long_or_lat_value_list[1]
    else:
        lang_or_lat_minute = 0
    # 秒提取
    long_or_lat_value_list = long_or_lat_value.split('″')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_second = long_or_lat_value_list[0]
    else:
        lang_or_lat_second = 0
    # 形成精确的小数
    lang_or_lat_value_fraction = Fraction(lang_or_lat_degree) * 3600 + Fraction(lang_or_lat_minute) * 60 + Fraction(lang_or_lat_second)
    return lang_or_lat_value_fraction * negative


def transform_longitude_or_latitude_into_float(long_or_lat:str) -> float:
    """
    转换经度和纬度字符串描述为精确小数格式
    :param long_or_lat: str ; 经度和纬度字符串表示
    :return: float ; 精确的小数描述方式
    """
    if isinstance(long_or_lat, str):
        long_or_lat = long_or_lat.upper().strip().replace(' ', '')
    # 将 W 和 S 修改为负值，将 N 和 E 修改为正值
    negative = -1 if long_or_lat.endswith(('W', 'S')) else 1
    # 提取经度和纬度中的度分秒
    long_or_lat_value = long_or_lat[1:]
    lang_or_lat_degree = lang_or_lat_minute = lang_or_lat_second = None
    # 度提取
    long_or_lat_value_list = long_or_lat_value.split('°')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_degree = long_or_lat_value_list[0]
        long_or_lat_value = long_or_lat_value_list[1]
    else:
        lang_or_lat_degree = 0
    # 分提取
    long_or_lat_value_list = long_or_lat_value.split('′')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_minute = long_or_lat_value_list[0]
        long_or_lat_value = long_or_lat_value_list[1]
    else:
        lang_or_lat_minute = 0
    # 秒提取
    long_or_lat_value_list = long_or_lat_value.split('″')
    if len(long_or_lat_value_list) == 2:
        lang_or_lat_second = long_or_lat_value_list[0]
    else:
        lang_or_lat_second = 0
    # 形成精确的小数
    lang_or_lat_value_float = float(lang_or_lat_degree) * 3600 + float(lang_or_lat_minute) * 60 + float(lang_or_lat_second)
    return lang_or_lat_value_float * negative









if __name__ == '__main__':
    # 经度 - x 轴 东经
    longitude = 'E116°18′45.37″'
    # 维度 - y 轴 北半球
    latitude = 'N39°59′35.38″'
    # 将经纬度转化为标准格式化形式
    flag, longitude_format = validate_longitude_or_latitude_format(longitude)
    print(longitude, flag, longitude_format)
    flag, latitude_format = validate_longitude_or_latitude_format(latitude)
    print(latitude, flag, latitude_format)
    # 将经纬度转化为精确分数
    longitude_fraction = transform_longitude_or_latitude_into_fraction(longitude_format)
    print(longitude, longitude_format, longitude_fraction,longitude_fraction.todecimal(decplaces=2))
    latitude_fraction = transform_longitude_or_latitude_into_fraction(latitude_format)
    print(latitude, latitude_format, latitude_fraction, latitude_fraction.todecimal(decplaces=2))